package com.oa.erp.ass.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mdp.core.service.BaseService;
import com.mdp.core.utils.BaseUtils;
import com.mdp.safe.client.entity.User;
import com.mdp.safe.client.utils.LoginUtils;
import com.oa.erp.ass.entity.AssetCard;
import com.oa.erp.ass.entity.AssetCardOper;
import com.oa.erp.ass.entity.AssetDetail;
import com.oa.erp.ass.enums.AssetStatusEnum;
import com.oa.erp.ass.enums.MngStatusEnum;
import com.oa.erp.ass.mapper.AssetDetailMapper;
import com.oa.erp.pur.entity.StockIn;
import com.oa.erp.pur.entity.StockInDetail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author maimeng-mdp code-gen
 * @since 2023年10月8日
 */
@Service
public class AssetDetailService extends BaseService<AssetDetailMapper, AssetDetail> {
    static Logger logger = LoggerFactory.getLogger(AssetDetailService.class);

    /**
     * 自定义查询，支持多表关联
     *
     * @param page 分页条件
     * @param ew   一定要，并且必须加@Param("ew")注解
     * @param ext  如果xml中需要根据某些值进行特殊处理，可以通过这个进行传递，非必须，注解也可以不加
     * @return
     */
    public List<Map<String, Object>> selectListMapByWhere(IPage page, QueryWrapper ew, Map<String, Object> ext) {
        return baseMapper.selectListMapByWhere(page, ew, ext);
    }

    @Autowired
    private AssetCardOperService assetCardOperService;

    @Autowired
    private AssetCardService assetCardService;

    private final String NO = "0";
    private final String YES = "1";

    /** 请在此类添加自定义函数 */


    /**
     * 资产入库添加资产操作
     */
    @Transactional
    public void insertAssetDetail(StockIn stockIn, List<StockInDetail> stockInDetails) {
        User user = LoginUtils.getCurrentUserInfo();
        Map<String, StockInDetail> stockInDetailMap = new HashMap<>();
        for (StockInDetail stockInDetail : stockInDetails) {
            if (stockInDetailMap.containsKey(stockInDetail.getAssetSn())) {
                StockInDetail stockInDetail0 = stockInDetailMap.get(stockInDetail.getAssetSn());
                stockInDetail0.setInNum(stockInDetail0.getInNum().add(stockInDetail.getInNum()));
            } else {
                stockInDetailMap.put(stockInDetail.getAssetSn(), stockInDetail);
            }

        }
        List<StockInDetail> stockInDetailNew = stockInDetailMap.values().stream().collect(Collectors.toList());
        //1.添加资产表
        List<AssetDetail> assetDetailsInsert = new ArrayList<>();
        List<AssetDetail> assetDetailsUpdate = new ArrayList<>();
        List<AssetCardOper> assetDetailOpers = new ArrayList<>();
        List<AssetCard> assetCardList = new ArrayList<>();
        List<String> assetSnList = stockInDetails.stream().map(i -> i.getAssetSn()).collect(Collectors.toList());

        List<AssetDetail> assetDetailsDb = this.selectListMapByWhere(null, null, map("assetSns", assetSnList, "branchId", stockIn.getReqBranchId())).stream().map(i -> BaseUtils.fromMap(i, AssetDetail.class)).collect(Collectors.toList());
        List<StockInDetail> stockDetailsInsert = new ArrayList<>();
        List<StockInDetail> stockDetailsUpdate = new ArrayList<>();

        for (StockInDetail stockInDetail : stockInDetailNew) {
            if (assetDetailsDb.stream().filter(i -> i.getAssetSn().equals(stockInDetail.getAssetSn())).findAny().isPresent()) {
                stockDetailsUpdate.add(stockInDetail);
            } else {
                stockDetailsInsert.add(stockInDetail);
            }
        }


        for (StockInDetail stock : stockDetailsInsert) {
            AssetDetail target = new AssetDetail();
            BeanUtils.copyProperties(stock, target);
            //生成Id
            target.setId(this.createKey("id"));
            //设置入库数量
            target.setStockNum(stock.getInNum());
            //设置入库单
            target.setReceiptNo(stockIn.getId());
            //设置创建人id，创建人名称，创建时间，修改人..
            target.setCreateUserid(user.getUserid());
            target.setCreateTime(new Date());
            target.setCreateUsername(user.getUsername());
            target.setLastEditUserid(user.getUserid());
            target.setLastEditTime(new Date());
            target.setLastEditUsername(user.getUsername());
            target.setWarehouseDate(new Date());
            assetDetailsInsert.add(target);

            //如果需要生成资产卡片
            if ("1".equals(stockIn.getIsAssetCard())) {
                //如果需要按入库数量进行拆分
                if ("1".equals(stockIn.getCardDisByNum())) {
                    List<String> assetSns = this.assetCardService.batchCreateAssetSn(target.getAssetSn(), target.getBranchId(), stock.getInNum().intValue());
                    for (int i = 0; i < stock.getInNum().intValue(); i++) {
                        //组装资产卡片对象
                        AssetCard assetCard = this.transformAssetCard(target);
                        assetCard.setPassetSn(target.getPassetSn());
                        assetCard.setAssetSn(assetSns.get(i));
                        assetCardList.add(assetCard);

                        //组装资产卡片操作记录对象
                        AssetCardOper assetDetailOper = this.transformCardOper(stockIn, target, assetCard, stock);
                        assetDetailOpers.add(assetDetailOper);
                    }
                } else {
                    List<String> assetSns = this.assetCardService.batchCreateAssetSn(target.getAssetSn(), target.getBranchId(), 1);
                    //组装资产卡片对象
                    AssetCard assetCard = this.transformAssetCard(target);
                    assetCard.setPassetSn(target.getAssetSn());
                    assetCard.setAssetSn(assetSns.get(0));
                    assetCardList.add(assetCard);
                    //组装资产卡片操作记录对象
                    AssetCardOper assetDetailOper = this.transformCardOper(stockIn, target, assetCard, stock);
                    assetDetailOpers.add(assetDetailOper);
                }
            }
        }

        for (StockInDetail stock : stockDetailsUpdate) {
            AssetDetail targetDb = assetDetailsDb.stream().filter(i -> i.getAssetSn().equals(stock.getAssetSn())).findFirst().get();
            AssetDetail target = new AssetDetail();
            BeanUtils.copyProperties(targetDb, target);
            target.setStockNum(stock.getInNum());

            assetDetailsUpdate.add(target);
            //如果需要生成资产卡片
            if ("1".equals(stockIn.getIsAssetCard())) {
                //如果需要按入库数量进行拆分
                if ("1".equals(stockIn.getCardDisByNum())) {
                    List<String> assetSns = this.assetCardService.batchCreateAssetSn(target.getAssetSn(), target.getBranchId(), stock.getInNum().intValue());
                    for (int i = 0; i < stock.getInNum().intValue(); i++) {
                        //组装资产卡片对象
                        AssetCard assetCard = this.transformAssetCard(target);
                        assetCard.setPassetSn(target.getPassetSn());
                        assetCard.setAssetSn(assetSns.get(i));
                        assetCardList.add(assetCard);

                        //组装资产卡片操作记录对象
                        AssetCardOper assetDetailOper = this.transformCardOper(stockIn, target, assetCard, stock);
                        assetDetailOpers.add(assetDetailOper);
                    }
                } else {
                    List<String> assetSns = this.assetCardService.batchCreateAssetSn(target.getAssetSn(), target.getBranchId(), 1);
                    //组装资产卡片对象
                    AssetCard assetCard = this.transformAssetCard(target);
                    assetCard.setPassetSn(target.getAssetSn());
                    assetCard.setAssetSn(assetSns.get(0));
                    assetCardList.add(assetCard);
                    //组装资产卡片操作记录对象
                    AssetCardOper assetDetailOper = this.transformCardOper(stockIn, target, assetCard, stock);
                    assetDetailOpers.add(assetDetailOper);
                }
            }
        }
        if (assetDetailsInsert.size() > 0) {

            this.batchInsert(assetDetailsInsert);
        }
        //2.添加卡片表
        if (!CollectionUtils.isEmpty(assetCardList)) {
            assetCardService.batchInsert(assetCardList);
        }

        //3.添加资产卡片操作表,记录资产入库操作
        if (!CollectionUtils.isEmpty(assetDetailOpers)) {
            assetCardOperService.batchInsert(assetDetailOpers);
        }


        if (assetDetailsUpdate.size() > 0) {
            this.batchUpdateAssetDetailStockNum(assetDetailsUpdate);
        }

    }

    /**
     * 增量更新资产的库存数量
     *
     * @param assetDetailsUpdate
     */
    public void batchUpdateAssetDetailStockNum(List<AssetDetail> assetDetailsUpdate) {
//		super.update("batchUpdateAssetDetailStockNum",assetDetailsUpdate);
        baseMapper.batchUpdateAssetDetailStockNum(assetDetailsUpdate);
    }

    @Transactional
    public AssetCardOper transformCardOper(StockIn stockIn, AssetDetail target, AssetCard assetCard, StockInDetail stock) {
        AssetCardOper assetDetailOper = new AssetCardOper();
        //添加资产操作记录
        BeanUtils.copyProperties(stock, assetDetailOper);
        //设置资产Id
        assetDetailOper.setCardId(assetCard.getCardId());
        //设置主键Id
        assetDetailOper.setId(this.createKey("id"));
        //设置资产之后状态
        assetDetailOper.setAssetStatusAfter(AssetStatusEnum.LEAVEUNUSED.getStatus());
        //设置资产之前状态
        assetDetailOper.setAssetStatusBefore(null);
        assetDetailOper.setAdjustStockNum(new BigDecimal(1));
        assetDetailOper.setCreateDate(target.getCreateTime());
        assetDetailOper.setRequireId(stockIn.getId());
        assetDetailOper.setAllocDate(new Date());
        return assetDetailOper;
    }

    @Transactional
    public AssetCard transformAssetCard(AssetDetail target) {
        AssetCard assetCard = new AssetCard();
        BeanUtils.copyProperties(target, assetCard);
        //设置资产卡片id
        assetCard.setCardId(assetCardService.createKey("cardId"));
        //设置资产id关联
        assetCard.setDetailId(target.getId());
        //设置资产状态为闲置
        assetCard.setCardStatus(AssetStatusEnum.LEAVEUNUSED.getStatus());
        //设置资产存入仓库信息
        assetCard.setCardType(MngStatusEnum.SUBMIT.getStatus());
        //未在盘点中
        assetCard.setInventoryTask("0");
        return assetCard;
    }

    public String createAssetSn(String categoryId, String branchId) {
        AssetDetail assetDetail = new AssetDetail();
        assetDetail.setBranchId(branchId);
        assetDetail.setCategoryId(categoryId);
        long num = this.countByWhere(assetDetail);
        String numStr = (num + 1) + "";
        int lenght = 6 - numStr.length();
        String suffix = "";
        for (int i = 0; i < lenght; i++) {
            suffix = suffix + "0";
        }
        suffix = suffix + numStr;
        String assetSn = categoryId + suffix;
        return assetSn;
    }
}

